Skip to content

optee-teec: refactor plugin support#296

Draft
ivila wants to merge 1 commit intoapache:mainfrom
ivila:plugin_build_zc_0429
Draft

optee-teec: refactor plugin support#296
ivila wants to merge 1 commit intoapache:mainfrom
ivila:plugin_build_zc_0429

Conversation

@ivila
Copy link
Copy Markdown
Contributor

@ivila ivila commented Apr 29, 2026

  • Introduce optee-teec-plugin-bindgen crate to generate plugin bindings for plugin developers, replacing optee-teec-macros.
  • Refactor optee-teec::PluginParameters and add additional methods.
  • Update optee-teec-sys::PluginMethod to latest version.

With these changes, plugin development now only requires adding optee-teec-plugin-bindgen as a build dependency and including the generated artifact in lib.rs.

Why not use a proc macro?

I have thought about implementing a declare_supp_plugin macro like thisdemo:

declare_supp_plugin!(
    name: "my_plugin",
    uuid: "ef620757-fa2b-4f19-a1c4-6e51cfe4c0f9",
    init: my_init,
    invoke: my_invoke,
);

Developers can use it like:

use optee_teec::{declare_supp_plugin, PluginParameters};

fn plugin_init() -> optee_teec::Result<()> {
    println!("*plugin*: init, version: {}", env!("CARGO_PKG_VERSION"));
    Ok(())
}

fn plugin_invoke(_: &mut PluginParameters) -> optee_teec::Result<()> {
    println!("*plugin*: invoke");
    Ok(())
}

declare_supp_plugin!(
    name: "syslog",
    uuid: "ef620757-fa2b-4f19-a1c4-6e51cfe4c0f9",
    init: plugin_init,
    invoke: plugin_invoke,
);

The main issue is that developers may provide the UUID through a variable. Due to the limitations of proc macros, we cannot resolve the value of that variable during macro expansion. As a result, the UUID would need to be parsed and converted at runtime.

declare_supp_plugin!(
    name: "my_plugin",
    uuid: proto::PLUGIN_UUID,  // proc_macro cannot resolve the value at compile time.
    init: my_init,
    invoke: my_invoke,
);

However, this introduces another problem: what happens if UUID parsing fails? Triggering a panic in a shared library is not a good idea and should be avoided.

@ivila ivila force-pushed the plugin_build_zc_0429 branch 2 times, most recently from 903257d to 4a48066 Compare April 29, 2026 08:36
Comment thread examples/supp_plugin-rs/plugin/build.rs Outdated
Comment on lines +22 to +23
"init",
"invoke",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see why we're avoiding macros, but using strings for function names is a bit weird.
Since most users don't need custom names anyway, how about using defaults like plugin_init and plugin_invoke? Then the default constructor only requires the name and UUID. This would clean up the API and eliminate potential typos in build.rs.

We can also provide one more constructor that accepts the customized fn name if you'd like to.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good!😃

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have restored optee-teec-macros and am considering using macros to generate the injected functions automatically. What do you think about this approach?

With this solution, developers would apply macros to their init and invoke functions:

// lib.rs
#[derive_raw_plugin_init]
fn init() -> optee_teec::Result<()> {
    Ok(())
}

#[derive_raw_plugin_invoke]
fn invoke(_: &mut optee_teec::PluginParameters) -> optee_teec::Result<()> {
    Ok(())
}

// build.rs
fn main() -> anyhow::Result<()> {
    Config::new(Uuid::parse_str(proto::PLUGIN_UUID)?)
        .with_name("syslog")
        .build()?;

    Ok(())
}

If they need to customize the generated raw function name, it could work like this:

// lib.rs
#[derive_raw_plugin_init(raw_name = "raw_func_name")]
fn init() -> optee_teec::Result<()> {
    Ok(())
}

#[derive_raw_plugin_invoke]
fn invoke(_: &mut optee_teec::PluginParameters) -> optee_teec::Result<()> {
    Ok(())
}

// build.rs
fn main() -> anyhow::Result<()> {
    Config::new(Uuid::parse_str(proto::PLUGIN_UUID)?)
        .with_name("syslog")
        .with_init_fn_name("raw_func_name")
        .build()?;

    Ok(())
}

@ivila ivila force-pushed the plugin_build_zc_0429 branch 2 times, most recently from f93188d to 2808bfb Compare April 30, 2026 03:26
@ivila ivila marked this pull request as draft April 30, 2026 03:35
* Introduce optee-teec-plugin-bindgen crate to generate plugin bindings
  for plugin developers, replacing `plugin-static.rs` file.
* Refactor optee-teec::PluginParameters and add additional methods.
* Update optee-teec-sys::PluginMethod to latest version.
* optee-teec-macros: rename `plugin_init` to `derive_raw_plugin_init`,
  and rename `plugin_invoke` to `derive_raw_plugin_invoke`.
@ivila ivila force-pushed the plugin_build_zc_0429 branch from 2808bfb to 22137c5 Compare April 30, 2026 03:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants